﻿using System.Net;
using System.IO.Compression;
using System.IO;
using HtmlAgilityPack;
using System.Collections.Generic;
using System;

namespace ZhiHuSpider
{
    public class service
    {
        public service() { }

        public string Spider(string url)
        {
            WebClient client = new WebClient();
            client.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            client.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate, sdch");
            client.Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-CN,zh;q=0.8");
            client.Headers.Add(HttpRequestHeader.UserAgent, "ozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36");
            var data = client.DownloadData(url);
            string html = "";
            GZipStream gzip = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
            using (StreamReader reader = new StreamReader(gzip))
            {
                html = reader.ReadToEnd();
            }
            return html;
        }



        public ZhiHuModel Analytical(string html, string url)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            ZhiHuModel model = new ZhiHuModel();

            model.questionTitle = doc.DocumentNode.SelectSingleNode("//*[@id='zh-question-title']/h2") == null ? "" : doc.DocumentNode.SelectSingleNode("//*[@id='zh-question-title']/h2").InnerText;
            model.questionDetail = doc.DocumentNode.SelectSingleNode("//*[@id='zh-question-detail']/div").InnerText == null ? "" : doc.DocumentNode.SelectSingleNode("//*[@id='zh-question-detail']/div").InnerText;

            List<AnswerModel> answerList = new List<AnswerModel>();
            HtmlNode node = doc.DocumentNode.SelectSingleNode("//*[@id='zh-question-answer-wrap']");
            HtmlNodeCollection CNodes = node.ChildNodes;

            //清除文本节点#text
            for (int i = 0; i < CNodes.Count; )
            {
                if (CNodes[i].InnerHtml.Trim() == "")
                {
                    CNodes.Remove(CNodes[i]);
                }
                else
                {
                    i++;
                }
            }

            if (CNodes.Count > 0)
            {
                foreach (HtmlNode childNode in CNodes)
                {
                    AnswerModel answer = new AnswerModel();
                    answer.answerAuthor = childNode.SelectSingleNode(childNode.XPath + "/div[2]/div[1]/h3/a[2]") == null ? "知乎用户" : childNode.SelectSingleNode(childNode.XPath + "/div[2]/div[1]/h3/a[2]").InnerText.Trim();
                    List<AskModel> askList = new List<AskModel>();
                    if (answer.answerAuthor != "知乎用户")
                    {
                        string authorIdUrl = childNode.SelectSingleNode(childNode.XPath + "/div[2]/div[1]/h3/a[2]").Attributes[1].Value;
                        HtmlDocument doc3 = new HtmlDocument();
                        string askPage = Spider(url + authorIdUrl + "/asks");
                        doc3.LoadHtml(askPage);
                        HtmlNodeCollection CNodesAsk = doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list']").ChildNodes;
                        for (int i = 0; i < CNodesAsk.Count; )
                        {
                            if (CNodesAsk[i].InnerHtml.Trim() == "")
                            {
                                CNodesAsk.Remove(CNodesAsk[i]);
                            }
                            else
                            {
                                i++;
                            }
                        }

                        foreach (HtmlNode nodeAsk in CNodesAsk)
                        {
                            AskModel ask = new AskModel();
                            ask.title = doc3.DocumentNode.SelectSingleNode(nodeAsk.XPath + "/div/h2/a") == null ? "" : doc3.DocumentNode.SelectSingleNode(nodeAsk.XPath + "/div/h2/a").InnerText;
                            ask.author = doc3.DocumentNode.SelectSingleNode("//*[@id='zh-pm-page-wrap']/div[1]/div[1]/div[1]/div[2]/a") == null ? "" : doc3.DocumentNode.SelectSingleNode("//*[@id='zh-pm-page-wrap']/div[1]/div[1]/div[1]/div[2]/a").InnerText;
                            askList.Add(ask);
                        }

                        if (doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list-outer']/div[2]") != null)
                        {
                            if (doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list-outer']/div[2]/div") != null)
                            {
                                HtmlNodeCollection CNodesPages = doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list-outer']/div[2]/div").ChildNodes;
                                for (int i = 0; i < CNodesPages.Count; )
                                {
                                    if (CNodesPages[i].InnerHtml.Trim() == "")
                                    {
                                        CNodesPages.Remove(CNodesPages[i]);
                                    }
                                    else
                                    {
                                        i++;
                                    }
                                }
                                int count = CNodesPages.Count;
                                string totalpage = doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list-outer']/div[2]/div/span[" + (count - 1) + "]") == null ? "1" : doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list-outer']/div[2]/div/span[" + (count - 1) + "]").InnerText;
                                int pages = Convert.ToInt32(totalpage) - 1;
                                if (pages > 1)
                                {
                                    for (int j = 2; j <= pages; j++)
                                    {
                                        string pageHtml = Spider(url + authorIdUrl + "/asks?page=" + j);
                                        doc3.LoadHtml(pageHtml);
                                        HtmlNodeCollection CNodesAskPages = doc3.DocumentNode.SelectSingleNode("//*[@id='zh-profile-ask-list']").ChildNodes;
                                        for (int i = 0; i < CNodesAskPages.Count; )
                                        {
                                            if (CNodesAskPages[i].InnerHtml.Trim() == "")
                                            {
                                                CNodesAskPages.Remove(CNodesAskPages[i]);
                                            }
                                            else
                                            {
                                                i++;
                                            }
                                        }
                                        foreach (HtmlNode nodeAskPage in CNodesAskPages)
                                        {
                                            AskModel ask = new AskModel();

                                            ask.title = doc3.DocumentNode.SelectSingleNode(nodeAskPage.XPath + "/div/h2/a") == null ? "" : doc3.DocumentNode.SelectSingleNode(nodeAskPage.XPath + "/div/h2/a").InnerText;
                                            ask.author = childNode.SelectSingleNode(childNode.XPath + "/div[2]/div[1]/h3/a[2]") == null ? "" : childNode.SelectSingleNode(childNode.XPath + "/div[2]/div[1]/h3/a[2]").InnerText;
                                            askList.Add(ask);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    model.ask = askList;

                    answer.answerContent = childNode.SelectSingleNode(childNode.XPath + "/div[3]/div[1]") == null ? "" : childNode.SelectSingleNode(childNode.XPath + "/div[3]/div[1]").InnerText;

                    if (childNode.SelectSingleNode(childNode.XPath + "/div[3]/div[1]/a[@class='toggle-expand']") != null)
                    {
                        string urlMore = childNode.SelectSingleNode(childNode.XPath + "/div[3]/div[1]/a[@class='toggle-expand']").Attributes[0].Value;
                        string moreContent = Spider(url + urlMore);
                        HtmlDocument doc2 = new HtmlDocument();
                        doc2.LoadHtml(moreContent);
                        answer.answerContent = doc2.DocumentNode.SelectSingleNode("//*[@id='zh-question-answer-wrap']/div/div[3]/div") == null ? "" : doc2.DocumentNode.SelectSingleNode("//*[@id='zh-question-answer-wrap']/div/div[3]/div").InnerHtml;
                    }
                    answerList.Add(answer);
                }
            }
            model.answer = answerList;
            return model;
        }
    }
}
